package com.efamily.ewallet.client.profit.widget;

import java.util.Date;
import java.util.List;

import com.efamily.ewallet.client.account.bean.AccountBean;
import com.efamily.ewallet.client.common.DefaultAsyncCallback;
import com.efamily.ewallet.client.common.CustomEvents;
import com.efamily.ewallet.client.common.CustomEventType;
import com.efamily.ewallet.client.profit.bean.ProfitBean;
import com.efamily.ewallet.client.profit.bean.ProfitTypeBean;
import com.efamily.ewallet.client.profit.service.ProfitServiceAsync;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.mvc.Dispatcher;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.Composite;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.Window;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.extjs.gxt.ui.client.widget.form.DateField;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.NumberField;
import com.extjs.gxt.ui.client.widget.form.TextArea;
import com.extjs.gxt.ui.client.widget.form.FormPanel.LabelAlign;
import com.extjs.gxt.ui.client.widget.layout.ColumnData;
import com.extjs.gxt.ui.client.widget.layout.ColumnLayout;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.layout.FormData;
import com.extjs.gxt.ui.client.widget.layout.FormLayout;
import com.google.gwt.i18n.client.DateTimeFormat;

public class AddEditProfitWindow extends Window {
	private final ProfitServiceAsync profitService = ProfitServiceAsync.instance;
	private AddEditForm form = new AddEditForm();
	private ProfitBean profitBean = new ProfitBean();
	private AccountBean accountBean = new AccountBean();

	public AddEditProfitWindow() {
		setSize(500, 400);
		setPlain(true);
		setResizable(false);
		setClosable(true);
		setModal(true);
		setBlinkModal(true);
		setHeading("Add/Edit Profit");
		setLayout(new FitLayout());
		add(form);
	}

	public void showAddWindow(AccountBean accountBean) {
		this.accountBean = accountBean;
		profitBean = new ProfitBean();
		show();
	}

	public void showEditWindow(AccountBean accountBean, ProfitBean profit) {
		this.accountBean = accountBean;
		profitBean = profit;
		show();
	}

	private class AddEditForm extends Composite {

		private ComboBox<ProfitTypeBean> typeCmb = new ComboBox<ProfitTypeBean>();
		private DateField profitDateFld = new DateField();
		private NumberField valueFld = new NumberField();
		private TextArea descriptionArea = new TextArea();
		private Button saveBtn = new Button("Save");
		private FormPanel formPanel = new FormPanel();

		public AddEditForm() {
			buildForm();
			initComponent(formPanel);
			this.addListener(Events.Attach, new Listener<BaseEvent>() {
				public void handleEvent(BaseEvent be) {
					loadProfitTypes();
					if (profitBean.getId() == -1) {
						valueFld.setValue(0);
						profitDateFld.setValue(new Date());
						descriptionArea.reset();
					} else {
						valueFld.setValue(profitBean.getValue());
						profitDateFld.setValue(profitBean.getProfitDate());
						descriptionArea.setValue(profitBean.getDescription());
					}
				}
			});
		}

		private void buildForm() {
			FormData formData = new FormData("95%");
			// Left column
			LayoutContainer left = new LayoutContainer();
			left.setStyleAttribute("paddingRight", "10px");
			FormLayout layout = new FormLayout();
			layout.setLabelAlign(LabelAlign.TOP);
			left.setLayout(layout);
			typeCmb.setStore(new ListStore<ProfitTypeBean>());
			typeCmb.setAllowBlank(false);
			typeCmb.setFieldLabel("Type*");
			typeCmb.setEmptyText("Select type");
			typeCmb.setTypeAhead(true);
			//typeCmb.setTriggerAction(TriggerAction.ALL);
			typeCmb.setDisplayField("name");
			typeCmb.setForceSelection(true);
			left.add(typeCmb, formData);

			// Center column

			LayoutContainer center = new LayoutContainer();
			center.setStyleAttribute("paddingRight", "10px");
			center.setStyleAttribute("paddingLeft", "10px");
			layout = new FormLayout();
			layout.setLabelAlign(LabelAlign.TOP);
			center.setLayout(layout);
			valueFld.setFieldLabel("Value*");
			valueFld.setAllowBlank(false);
			valueFld.setSelectOnFocus(true);
			center.add(valueFld, formData);

			// Right column

			LayoutContainer right = new LayoutContainer();
			right.setStyleAttribute("paddingLeft", "10px");
			layout = new FormLayout();
			layout.setLabelAlign(LabelAlign.TOP);
			right.setLayout(layout);
			profitDateFld.setFieldLabel("Date*");
			profitDateFld.setAllowBlank(false);
			profitDateFld.getPropertyEditor().setFormat(
					DateTimeFormat.getFormat("EEE, d MMM, ''yy "));
			right.add(profitDateFld, new FormData("90%"));

			// Main panel

			LayoutContainer main = new LayoutContainer();
			main.setLayout(new ColumnLayout());
			main.add(left, new ColumnData(.33));
			main.add(center, new ColumnData(.33));
			main.add(right, new ColumnData(.33));

			// Form panel
			formPanel.setHeaderVisible(false);
			formPanel.setLabelAlign(LabelAlign.TOP);
			formPanel.add(main);
			descriptionArea.setFieldLabel("Description");
			descriptionArea.setEmptyText("You can type description here...");
			descriptionArea.setHeight(200);
			formPanel.add(descriptionArea, new FormData("100%"));
			saveBtn.addSelectionListener(new SelectionListener<ButtonEvent>() {
				@Override
				public void componentSelected(ButtonEvent ce) {
					try {
						addEditProfit();
					} catch (Exception ex) {
						MessageBox.alert("Operation failed", ex.getMessage(),
								null);
						ex.printStackTrace();
					}
				}
			});
			formPanel.addButton(saveBtn);
		}

		private void loadProfitTypes() {
			//TODO Change calling of this method. We should call its when new type was created
			profitService
					.getProfitTypes(accountBean, new DefaultAsyncCallback<List<ProfitTypeBean>>() {
						@Override
						public void onSuccess(List<ProfitTypeBean> profitTypes) {
							typeCmb.getStore().removeAll();
							typeCmb.getStore().add(profitTypes);
							if (profitBean.getId() == -1) {
								typeCmb.setValue(null);
								typeCmb.clearInvalid();
							} else {
								typeCmb.setValue(profitBean.getType());
							}
						}
					});

		}

		private void addEditProfit() {
			if (typeCmb.isValid() && valueFld.isValid()
					&& profitDateFld.isValid()) {
				ProfitTypeBean type = null;
				if (typeCmb.getValue() != null) {
					type = typeCmb.getValue();
				} else if (!typeCmb.getRawValue().isEmpty()) {
					type = new ProfitTypeBean(typeCmb.getRawValue());
				}
				profitBean.setType(type);
				profitBean.setValue(valueFld.getValue().doubleValue());
				profitBean.setDescription(descriptionArea.getValue());
				profitBean.setProfitDate(profitDateFld.getValue());
				profitService.addEditProfit(accountBean, profitBean,
						new DefaultAsyncCallback<Boolean>() {
							@Override
							public void onSuccess(Boolean isDone) {
								if (isDone) {
									Dispatcher.get().fireEvent(CustomEvents.ADD_PROFIT.getEventType());
									AddEditProfitWindow.this.hide();
								} else {
									MessageBox
											.alert(
													"Operation failed",
													"Some exception was thrown. Try again or ask administrator.",
													null);
								}
							}
						});

			}
		}
	}

}